package component.fulltextsearch.web.action;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexCommit;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.store.FSDirectory;

import common.util.KeyGenerator;
import component.fulltextsearch.constant.SearchConstant;
import component.fulltextsearch.entity.UserDocument;
import component.fulltextsearch.entity.UserInfoProxy;
import component.fulltextsearch.index.IDocumentSearch;
import component.fulltextsearch.index.IIndexOperate;
import component.fulltextsearch.index.SimpleDocumentSearch;
import component.fulltextsearch.index.SimpleIndexOperate;
import component.fulltextsearch.util.SearchConfigUtil;
import component.fulltextsearch.util.Page;

public class SearchAction {
	
	private IDocumentSearch documentSearch = new SimpleDocumentSearch();
	
	public void doSearch(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//request.setCharacterEncoding("utf-8"); 
		String queryExpression = request.getParameter("queryExpression");

		queryExpression = queryExpression == null?"":queryExpression;
		
		String field = null;
		Date startDate = null;//Constants.DATA_FORMAT.parse("20080601");
		Date endDate = null;//Constants.DATA_FORMAT.parse("20081201");;
		String advanceQueryExpression = request.getParameter("advanceQueryExpression");
		String advanceQueryExpression2 = queryExpression + ",,";//用于高级搜索页面显示的值
		if(advanceQueryExpression!=null && !"".equals(advanceQueryExpression)){
			//advanceQueryExpression = new String(advanceQueryExpression.getBytes("ISO-8859-1"),"utf-8");
			request.setAttribute("advanceQueryExpression", advanceQueryExpression);
			queryExpression = advanceQueryExpression;
			
			String dateFlag = request.getParameter("date");
			startDate = this.getStartDate(dateFlag);
			request.setAttribute("date", dateFlag);
			
			field = request.getParameter("position"); 
			request.setAttribute("position", field);
			
			advanceQueryExpression2 = this.getAdvanceQueryExpression(advanceQueryExpression);
		}
		
		request.setAttribute("queryExpression", queryExpression);
		request.setAttribute("advanceQueryExpression2", advanceQueryExpression2);
		
		String[] userArray = new String[]{UserInfoProxy.getUserInfo().getCurUserId(request)};
		String[] roleArray = UserInfoProxy.getUserInfo().getCurUserRoles(request);
		String[] sortFileds = null;
		String pageNoStr = request.getParameter("pageNo");
		String pageSizeStr = request.getParameter("pageSize");
		int pageNo = (pageNoStr == null ||"".equals(pageNoStr.trim())) ? 1 : Integer.parseInt(pageNoStr.trim());
		int pageSize = (pageSizeStr == null ||"".equals(pageSizeStr.trim())) ? Page.DEFAULT_PAGE_SIZE : Integer.parseInt(pageSizeStr.trim());;
		Page page = null;
		if (queryExpression != null && !queryExpression.trim().equals("")) {
			try {
				page = documentSearch.queryPageData(queryExpression, startDate, endDate, field, userArray, roleArray, sortFileds, pageNo, pageSize);				
			} catch (Exception e) {
				e.printStackTrace();
				page = new Page(0, 0, Page.DEFAULT_PAGE_SIZE, new ArrayList());
			}
		} else {
			page = new Page(0, 0, Page.DEFAULT_PAGE_SIZE, new ArrayList());
		}
		request.setAttribute("page", page);
	}	
	
	private static Date getStartDate(String flag){
		Calendar c = Calendar.getInstance();
		
		if("d".equals(flag)){
			//c.add( Calendar.DAY_OF_MONTH, -1 );
			c.add( Calendar.DATE, -1 );
		}else if("w".equals(flag)){
			//c.add( Calendar.DAY_OF_MONTH, -7 );
			c.add( Calendar.DATE, -7 );
		}else if("m".equals(flag)){
			c.add(Calendar.MONTH, -1);
		}else if("y".equals(flag)){
			c.add(Calendar.YEAR, -1);
		}else{
			return null;
		}
		return c.getTime();
	}
	
	/**
	 * 将高级搜索页面的查询表达式分隔成用逗号隔开的3个查询表达式
	 * @param advanceQueryExpression
	 * @return
	 */
	private String getAdvanceQueryExpression(String advanceQueryExpression){
		String[] expressions = advanceQueryExpression.split(" ");
		StringBuffer aExpression = new StringBuffer();
		StringBuffer bExpression = new StringBuffer();
		StringBuffer cExpression = new StringBuffer();
		for (int i = 0; i < expressions.length; i++) {
			String expression = expressions[i];
			//System.out.println("expression = " + expression);
			if (expression == null || "".equals(expression.trim())) continue;
			if(expression.trim().startsWith("-")){
				cExpression.append(" ").append(expression);
			}else if(expression.trim().startsWith("+") && expression.indexOf("(")==-1){
				aExpression.append(" ").append(expression);
			}else{
				bExpression.append(" ").append(expression);
			}
		}	
		
		String aExpressionStr = String.valueOf(aExpression).trim();
		if(aExpressionStr.length()>0){
			//aExpressionStr = aExpressionStr.substring(1);
			aExpressionStr = aExpressionStr.replaceAll("\\+", "");
		}
		
		String bExpressionStr = String.valueOf(bExpression).trim();
		if(bExpressionStr.length()>0){
			bExpressionStr = bExpressionStr.substring(2,bExpressionStr.length()-1);
		}
		
		String cExpressionStr = String.valueOf(cExpression).trim();
		if(cExpressionStr.length()>0){
			//cExpressionStr = cExpressionStr.substring(1);
			cExpressionStr = cExpressionStr.replaceAll("-", "");
		}
		
		return aExpressionStr + "," + bExpressionStr + "," + cExpressionStr;
	}
	
	public void toList(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doSearch(request, response);
	}
	
	public void toEdit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
		String queryExpression = request.getParameter("queryExpression");
		request.setAttribute("queryExpression", queryExpression);
		
		String flag = request.getParameter("flag");
		request.setAttribute("flag", flag);
		
		UserDocument userDoc = new UserDocument();;
		
		String fid = request.getParameter("fid");
		if(fid == null || "".equals(fid.trim())){//新增
			userDoc.setKeyValue("");
			userDoc.setKeywords("关键字101");
			userDoc.setName("标题101");
			userDoc.setSummary("摘要101");
			userDoc.setContent("内容101");
			userDoc.setCreateTime(new  Date());
			userDoc.setRightUsers("PUB");
			userDoc.setRightRoles("PUB");
			
			request.setAttribute("actionType", "add");
		}else{//修改,根据关键值来查找
			Document doc = this.getDocByKeyValue(fid);
			if(doc != null){
				String keyValue = doc.get(SearchConstant.NAME_KEYVALUE);
				String keywords = doc.get(SearchConstant.NAME_KEYWORDS);
				String name = doc.get(SearchConstant.NAME_NAME);
				String summary = doc.get(SearchConstant.NAME_SUMMARY);
				String content = doc.get(SearchConstant.NAME_CONTENT);
				String createTime = doc.get(SearchConstant.NAME_CREATETIME);
				String rightUsers = doc.get(SearchConstant.NAME_RIGHTUSERS);
				String rightRoles = doc.get(SearchConstant.NAME_RIGHTROLES);
				
				userDoc.setKeyValue(keyValue);
				userDoc.setKeywords(keywords);
				userDoc.setName(name);
				userDoc.setSummary(summary==null?"":summary.trim());
				userDoc.setContent(content==null?"":content.trim());
				userDoc.setRightUsers(rightUsers);
				userDoc.setRightRoles(rightRoles);
				try {
					userDoc.setCreateTime(SearchConstant.DATA_FORMAT.parse(createTime));
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			request.setAttribute("actionType", "modify");
		}
		request.setAttribute("userDoc", userDoc);
		
	}
	
	private Document getDocByKeyValue(String keyValue) throws IOException{
		String indexDirStr = SearchConfigUtil.getInstance().getProperty("indexdir");
		File indexDir = new File(indexDirStr);
		FSDirectory directory = FSDirectory.getDirectory(indexDir);
		IndexSearcher searcher = new IndexSearcher(directory);
		if (!indexDir.exists()) {
			System.out.println("The Lucene index is not exist");
			return null;
		}
		Term term = new Term(SearchConstant.NAME_KEYVALUE, keyValue.toLowerCase());
		TermQuery luceneQuery = new TermQuery(term);
		Hits hits = searcher.search(luceneQuery);

		return hits.doc(0);
	}
	
	public void doSave(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
		UserDocument doc = new UserDocument();
		
		Enumeration enumer = request.getParameterNames();
		while (enumer.hasMoreElements()) {
			String paramName = (String) enumer.nextElement();
			String paramValue = request.getParameter(paramName);
			if(paramName.indexOf("vo.")!=-1){
				String voName = paramName.substring(3);
				try {
					Field field = doc.getClass().getDeclaredField(voName);
					String typeName = field.getType().getName();
					if(!"java.util.Date".equals(typeName)){
						doc.setValue(voName, paramValue);
					}
				} catch (SecurityException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (NoSuchFieldException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
		String createTime = request.getParameter("vo.createTime");
		if(createTime!=null){
			try {
				doc.setCreateTime(SearchConstant.DATA_FORMAT.parse(createTime));
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		//doc.setIsDelete(SearchConstant.DELETE_FLAG);
		IIndexOperate operate = new SimpleIndexOperate();
		if(doc.getKeyValue() == null || "".equals(doc.getKeyValue())){
			doc.setKeyValue(new KeyGenerator.StringIDGenerator().generateID());
			operate.createIndex(doc);
		}else{
			operate.updateIndex(doc);
		}
		
		this.doSearch(request, response);
	}
	
	public void doDeleteAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
		String indexDir = SearchConfigUtil.getIndexdir();
		
		//this.deleteAllIndex(indexDir);
		IIndexOperate operate = new SimpleIndexOperate();
		operate.deleteAllIndex();
		
		this.doSearch(request, response);
	}
	
	public void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
		String indexDir = SearchConfigUtil.getIndexdir();
		
		
		String[] fidArr = request.getParameterValues("fid");
		
		Set set = new HashSet();
		for(int i = 0;i<fidArr.length;i++){
			set.add(fidArr[i]);
		}
		
		IIndexOperate operate = new SimpleIndexOperate();
		operate.deleteIndex(set);
		
		this.doSearch(request, response);
	}
	
	/**
	 * 删除指定索引目录下的所有索引
	 * @param indexDirStr：索引目录
	 * @return deleteIndex 删除的索引数
	 */
	public static int deleteAllIndex(String indexDirStr) {
		IndexReader reader = null;
		File file = new File(indexDirStr);
		int deleteIndex = 0;
		if (file.exists() && file.isDirectory()) {
			try {
				reader = IndexReader.open(indexDirStr);
				for (int i = 0; i < reader.maxDoc(); i++) {
					reader.deleteDocument(i);
					deleteIndex ++;
				}
			} catch (CorruptIndexException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				if (reader != null) {
					try {
						reader.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}
		System.out.println("删除了 " + deleteIndex + "条索引");
		return deleteIndex;
	}  
	
	public static void main(String[] args) {
		//Date d = getStartDate("d");
		//Date d = getStartDate("w");
		//Date d = getStartDate("m");
		Date d = getStartDate("y");
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String currentDate = dateFormat.format(d);
		System.out.println(currentDate);
		
		String paramName = "vo.name";
		String voName = paramName.substring(3);
		System.out.println(voName);
		
		UserDocument doc = new UserDocument();
		try {
			Field field = doc.getClass().getDeclaredField("createTime");
			System.out.println(field.getType().getName());
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
					
	}
}
